/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import model.estrutura.MalhaIrregular;

/**
 *
 * @author Thiago
 */
public class Oculta {
    MalhaIrregular malha;
    Camera cam;

    public Oculta(MalhaIrregular malha, Camera cam) {
        this.malha = malha;
        this.cam = cam;
    }

    public void executaConstante() {
        double[] vp = new double[3];
        double[] n;
        double[] a = new double[3];
        double[] b = new double[3];
        double[] ptsN;
        
        double visivel;

        // faz p - vrp
        vp = vrpP(cam, vp);

        // normaliza p - vrp
        n = normaliza(vp);

        // pega matriz da malha
        double[][] m = malha.getMatriz();

        for (int i = 0; i < m[0].length - 3; i += 3) {
            // faz ponto 0 - 1
            a[0] = m[0][i] - m[0][i + 1];
            a[1] = m[1][i] - m[1][i + 1];
            a[2] = m[2][i] - m[2][i + 1];

            // faz ponto 2 - 1
            b[0] = m[0][i + 2] - m[0][i + 1];
            b[1] = m[1][i + 2] - m[0][i + 1];
            b[2] = m[2][i + 2] - m[0][i + 1];

            // multiplica os pontos dos 2 vetores de pontos
            ptsN = multVetor(a, b);

            // normaliza os pontos multiplicados
            ptsN = normaliza(ptsN);

            // multiplica os pontos normalizados com o vetor U
            visivel = escalarVetor(n, ptsN);

            if (visivel < 0) {
                malha.addListaCor(i, 1);
            }else{
                malha.addListaCor(i, -1);
            }
        }
    }
    
    public MalhaIrregular getMalha() {
        return malha;
    }

    public double[] vrpP(Camera cam, double[] pontos) {
        pontos[0] = cam.getVx() - cam.getPx();
        pontos[1] = cam.getVy() - cam.getPy();
        pontos[2] = cam.getVz() - cam.getPz();
        return pontos;
    }

    public double[] normaliza(double[] vetor) {
        double[] v = new double[3];
        v[0] = vetor[0] / Math.sqrt(Math.pow(vetor[0], 2) + Math.pow(vetor[1], 2) + Math.pow(vetor[2], 2));
        v[1] = vetor[1] / Math.sqrt(Math.pow(vetor[0], 2) + Math.pow(vetor[1], 2) + Math.pow(vetor[2], 2));
        v[2] = vetor[2] / Math.sqrt(Math.pow(vetor[0], 2) + Math.pow(vetor[1], 2) + Math.pow(vetor[2], 2));
        return v;
    }

    public double[] multVetor(double[] a, double[] b) {
        double[] m = new double[3];
        m[0] = b[1] * a[2] - (b[2] * a[1]);
        m[1] = b[2] * a[0] - (b[0] * a[2]);
        m[2] = b[0] * a[1] - (b[1] * a[0]);
        return m;
    }

    public double escalarVetor(double[] a, double[] b) {
        return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
    }

    public double[] menor(double[][] m, int j, double menor[]) {
        if (m[0][j] < menor[0]) {
            menor[0] = m[0][j];
        }
        if (m[1][j] < menor[1]) {
            menor[1] = m[1][j];
        }
        if (m[2][j] < menor[2]) {
            menor[2] = m[2][j];
        }
        return menor;
    }

    public double[] maior(double[][] m, int j, double maior[]) {
        if (m[0][j] > maior[0]) {
            maior[0] = m[0][j];
        }
        if (m[1][j] > maior[1]) {
            maior[1] = m[1][j];
        }
        if (m[2][j] > maior[2]) {
            maior[2] = m[2][j];
        }
        return maior;
    }

    public double[] centro(double[] maior, double[] menor) {
        double[] c = new double[3];
        c[0] = (maior[0] + menor[0]) / 2;
        c[1] = (maior[1] + menor[1]) / 2;
        c[2] = (maior[2] + menor[2]) / 2;
        return c;
    }
}
